/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lk;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;
import java.lang.Math;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Random;

/**
 *
 * @author apple
 */
public class LinKernighan {
    static ArrayList<Continente> arContinente = new ArrayList<Continente>();
    static ArrayList<Pais> arPais = new ArrayList<Pais>();
    static ArrayList<Pedido> arPedido = new ArrayList<Pedido>();
    static ArrayList<Almacen> arAlmacen = new ArrayList<Almacen>();
    static ArrayList<Vuelo> arVuelo = new ArrayList<Vuelo>();
    static ArrayList<VueloXRuta> arVueloXRuta = new ArrayList<VueloXRuta>(); //ver si es necesario
    static ArrayList<ReservaAlmacen> arReserva = new ArrayList<ReservaAlmacen>();
    
    Ruta ruta;
    public Pedido pedido;
    int  opt;
    
    public LinKernighan(){
        arContinente = new ArrayList<Continente>();
        arPais = new ArrayList<Pais>();
        arPedido = new ArrayList<Pedido>();
        arAlmacen = new ArrayList<Almacen>();
        arVuelo = new ArrayList<Vuelo>();
        arVueloXRuta = new ArrayList<VueloXRuta>();
    }

    public Ruta LK(Almacen origen, Almacen destino, Fecha fechaCreacion) throws IOException {
        int cantidad, j = 0; 
        opt = 2;
        
        ArrayList<Vuelo> vueloX;
        ArrayList<Vuelo> vueloY;
        ArrayList<ArrayList<Vuelo>>vuelosY;
        VueloXRuta vueloxruta = new VueloXRuta();
        
        Grasp g = new Grasp();
        
        ruta = new Ruta();
        
        ruta = g.generarRutaGrasp(origen, destino, fechaCreacion); //[1]
        utils.impresiones.imprimirRutaGrasp(ruta);
        //OBS aquí se debe analizar si es continental o intercontinental!!!!

        boolean tipo = origen.esContinental(destino);
        Fecha fechaFin;
        
        if(tipo)
            fechaFin = pedido.fechaCreacion.anhadirHoras(Constantes.MAX_TIEMPO_CONTINENTAL); 
        else
            fechaFin = pedido.fechaCreacion.anhadirHoras(Constantes.MAX_TIEMPO_INTERCONTINENTAL);
        

        Utils.imprimirResultado(ruta, pedido);
        if (ruta!=null){
            while (opt < ruta.vuelos.size()){
                cantidad = ruta.vuelos.size();
                for (int i=0; i < cantidad ; i++){
                    j=i;
                    if(j > ruta.vuelos.size()-opt) break;
                    else{
                        vueloX = vueloxruta.get(ruta,j, opt); 
                        if (vueloX == null) break;//[2]
                        //utils.impresiones.debugTramoX(ruta, opt, i, vueloX);
                        if(j==0) {
                            //OBS en algún momento debes pasar como parámetro la fecha de salida del vuelo que le sigue
                            //a vueloX.get(vueloX.size()-1) porque este es mi límite para vuelosY
                            //si este es el último vuelo de la ruta, entonces debes pasar como parámetro
                            //fechaRegistro.mas1o2dias(1 o 2 según corresponda) porque este será tu limitante
                            vuelosY = vueloxruta.getRandom(arVuelo, vueloX, opt, pedido.fechaCreacion, ruta.vuelos.get(j+opt).fechaSalida);
                        }  //[3] 
                        else if( (opt + j) == ruta.vuelos.size() ) {
                            vuelosY = vueloxruta.getRandom(arVuelo, vueloX, opt, ruta.vuelos.get(j-1).fechaLlegada, fechaFin);
                        } 
                        else {
                            vuelosY = vueloxruta.getRandom(arVuelo, vueloX, opt, ruta.vuelos.get(j-1).fechaLlegada, ruta.vuelos.get(j+opt).fechaSalida);
                        }  //[3] 
                        //utils.impresiones.debugTramosY(vuelosY, vueloX,ruta,opt);
                        vueloY = ruta.evaluarF(opt, vueloX, vuelosY); //[4]
                        if (!vueloY.isEmpty()){
                           ruta = vueloxruta.Reemplazar(ruta, vueloX, vueloY); //[5]
                           ruta.fechaSalida = ruta.vuelos.get(0).fechaSalida; 
                           ruta.fechaLlegada = ruta.vuelos.get(ruta.vuelos.size()-1).fechaLlegada;
                           System.out.println("***************************************LK opt:" + opt + "********************************************** ");
                           Utils.imprimirResultado(ruta, pedido);
                           break; 
                        }
                    }
                }
                if (j == (ruta.vuelos.size() -1)) {
                    opt++;
                }
                
           }
        }
       ruta.fechaSalida = ruta.vuelos.get(0).fechaSalida; 
       ruta.fechaLlegada = ruta.vuelos.get(ruta.vuelos.size()-1).fechaLlegada;
       return ruta; 
   }
}
